package com.tom.demo.security;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tom.demo.common.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @Author: LanQiang
 * @Date: 2023/01/18/16:16
 * @Description: 认证失败，抛出异常
 * 比如携带token,但是token过期了，或者是错误的token
      * 注意：只有通过配置类中配置接口权限，出现异常才会走这里的返回信息
     * 如果使用注解来校验权限是否满足，那么抛出的异常不会到这里，会被我们的全局异常所拦截
 */
@Component
@Slf4j
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
    @Resource
    private ObjectMapper objectMapper;
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        try {
            // 设置响应状态码和内容类型
            response.setStatus(401);
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            String servletPath = request.getServletPath();
            String jsonValue = objectMapper.writeValueAsString(Result.error("身份失效,请重新登录", 401, null));
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(jsonValue.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
            outputStream.close();
            log.error("AuthenticationEntryPoint<====>请求的地址是:{},异常是:{}",servletPath,authException.getMessage());
        } catch (JsonProcessingException e) {
            log.error("AuthenticationEntryPoint<====>对象转json失败!{}",e.getMessage());
        }
    }
}